const g = require("../utils/constants");
const { shuffle } = require("../utils/helper");
const { CellModel } = require("./cellModel");
const { phases } = require("../utils/data");

class GameModel {
    constructor() {
        // 所有格子
        this.cells = [];
        // 供选择的格子
        this.selectCells = [];
        this.level = cc.sys.localStorage.getItem("level") || 1;
        // 上次选中的格子, row * x + y
        this.lastSelected = cc.v2(-1, -1);
        // 需要更新的格子
        this.changeCells = [];
        // 需要更新的选项格子
        this.changeSelectCells = [];
        this.isFinish = false;
    }

    init() {
        // 坐标从1开始，坐标起始点从左上角开始
        for (let i=1; i <= g.PHASE_ROW; i++) {
            this.cells[i] = [];
            if(i <= g.SELECT_ROW) {
                this.selectCells[i] = [];
            }
            for (let j=1; j <= g.PHASE_COL; j++) {
                let m = new CellModel();
                m.x = i;
                m.y = j;
                this.cells[i][j] = m;
                if(this.selectCells[i]) {
                    m = new CellModel();
                    m.x = i;
                    m.y = j;
                    this.selectCells[i][j] = m;
                }
            }
        }
    }

    resetModel() {
        for (let i=1; i <= g.PHASE_ROW; i++) {
            for (let j=1; j <= g.PHASE_COL; j++) {
                this.cells[i][j].reset();
                if(this.selectCells[i] && this.selectCells[i][j]) {
                    this.selectCells[i][j].reset();
                }
            }
        }
        this.lastSelected = cc.v2(-1, -1);
    }

    updateLevel() {
        this.level++;
    }

    // 更新关卡题
    updatePhase() {
        const levelPhases = phases[this.level.toString()];
        if(!levelPhases){
            cc.log("game over, you win");
            this.isFinish = true;
            return;
        }
        let toSelect = [];
        for (let i=1; i <= g.PHASE_ROW; i++) {
            if(levelPhases[i.toString()] && levelPhases[i.toString()].empty) {
                // 待填充字段
                for(const v of levelPhases[i.toString()].empty) {
                    this.cells[i][parseInt(v)].input = levelPhases[i.toString()][v];
                     // 保存待填充位置
                    toSelect.push(levelPhases[i.toString()][v]);

                }
            }
            for (let j=1; j <= g.PHASE_COL; j++) {
                if(levelPhases[i.toString()] && levelPhases[i.toString()][j.toString()]) {
                    if(!this.cells[i][j].input) {
                        // 不需要填充
                        this.cells[i][j].name = levelPhases[i.toString()][j.toString()];
                    }
                }
            }
        }
        // 待选项
        toSelect = shuffle(toSelect);
        for (let i = 0; i < toSelect.length; i++) {
            // 第几行
            const r = Math.floor(i/g.PHASE_COL)+1;
            // 第几列
            const c = i - Math.floor(i/g.PHASE_COL)*g.PHASE_COL + 1;
            // 查找需要填充的汉字
            this.selectCells[r][c].name = toSelect[i];
        }
        const r = Math.floor(toSelect.length/g.PHASE_COL)+1;
        // 第几列
        const c = toSelect.length - Math.floor(toSelect.length/g.PHASE_COL)*g.PHASE_COL + 1;
        for (let i=r; i <= g.SELECT_ROW; i++) {
            for (let j=c; j <= g.PHASE_COL; j++) {
                // 清除多余汉字
                this.selectCells[i][j].name = "";
            }
        }
    }

    // 是否更新状态
    selectCell(x, y) {
        if (this.lastSelected.x === x && this.lastSelected.y === y) {
            // 如果点击的格子填了错误的汉字，将该汉字清除
            const cell = this.cells[x][y];
            if (cell.input && cell.name && cell.input !== cell.name) {
                this.selectCells[cell.fillX][cell.fillY].activeDisplay();
                this.selectCells[cell.fillX][cell.fillY].activeWordFadIn();
                this.changeSelectCells.push(this.selectCells[cell.fillX][cell.fillY]);
                cell.activeUpdateName("");
                cell.activeNormalWord();
                cell.setFillXY(0, 0);
                this.changeCells.push(cell);
            }
            return ;
        }
        if(this.cells[x][y].input === "") {
            // 不能点，否则会播放声音
            return ;
        }
        const lastSelected = cc.v2(this.lastSelected.x, this.lastSelected.y);
        this.lastSelected = cc.v2(x, y);
        this.cells[x][y].activeSelect();
        this.changeCells.push(this.cells[x][y]);
        if (lastSelected.x !== -1 && lastSelected.y !== -1) {
            this.cells[lastSelected.x][lastSelected.y].activeSelect();
            this.changeCells.push(this.cells[lastSelected.x][lastSelected.y]);
        }
    }

    // 填充选择的汉字
    fillCell(fillX, fillY) {
        if(!this.cells[this.lastSelected.x] || !this.cells[this.lastSelected.x][this.lastSelected.y]) {
            // 最后选择的格子无效
            return ;
        }
        const cell = this.cells[this.lastSelected.x][this.lastSelected.y];
        // 不为空且，有汉字
        if(cell.input === "" || cell.input === cell.name) {
            // 当前格子不可以填或者已经填对了
            return ;
        }
        const oldFillX = cell.fillX;
        const oldFillY = cell.fillY;
        // 可以填的格子
        cell.activeUpdateName(this.selectCells[fillX][fillY].name);
        cell.activeWordFadIn();
        // 之前填的格子恢复显示
        if(oldFillX !== 0 && oldFillY !== 0 ) {
            this.selectCells[oldFillX][oldFillY].activeDisplay();
            this.selectCells[oldFillX][oldFillY].activeWordFadIn();
            this.changeSelectCells.push(this.selectCells[oldFillX][oldFillY]);
        }
        // 新选的格子隐藏
        cell.setFillXY(fillX, fillY);
        this.selectCells[fillX][fillY].activeHide();
        this.changeSelectCells.push(this.selectCells[fillX][fillY]);
        // 填充的网格
        this.changeCells.push(cell);
        this.checkWord(cell);
    }

    // 校验
    checkWord(cell) {
        if (cell.name === cell.input) {
            // 填对了
            cell.activeCorrectWord();
            this.selectCells[cell.fillX][cell.fillY].input = cell.input;
        } else {
            cell.activeWrongWord();
        }
    }

    // 清除需要操作的格子
    cleanChange() {
        this.changeCells = [];
        this.changeSelectCells = [];
    }

    // 游戏结束
    isGameOver() {
        if(this.isFinish) {
            return false;
        }
        for (let row = 1; row < this.selectCells.length; row ++) {
            for (let col = 1; col < g.PHASE_COL; col++) {
                const cell = this.selectCells[row][col];
                if(cell.name !== cell.input) {
                    return false;
                }
            }
        }
        return true;
    }

    checkResult() {
        let isSuccess = true;
        for (let i = 1; i <= g.PHASE_ROW; i++) {
            for (let j = 1; j <= g.PHASE_COL; j++) {
                const cell = this.cells[i][j];
                if(cell.input !== "") {
                    // 需要填的格子
                    if(cell.name === ""  || cell.name !== cell.input) {
                        isSuccess = false;
                        break;
                    }
                }
            }
        }
        return isSuccess;
    }

    // 获取第几个需要填充的格子, 从 1 开始
    getInputCell(index) {
        let find = 0;
        for (let i=1; i <= g.PHASE_ROW; i++) {
            for (let j=1; j <= g.PHASE_COL; j++) {
                if (this.cells[i][j].input !== "") {
                    find++;
                    if(find === index) {
                        return this.cells[i][j];
                    }
                }
            }
        }
        return null;
    }

}

module.exports = {
    GameModel
}

// 交换
// c = a ^ b
// b = c ^ b
// a = c ^ b